core.tree = {};

core.tree.TREE_LEVEL_PADDING = 20;
core.tree.TREE_ITEM_HEIGHT = 20;
core.tree.SCROLLBAR_SIZE = 25;

core.tree.TreeItem = function(config){
    this.init(config);
}

core.extendClass('core.tree.TreeItem', 'core.Box');

core.tree.TreeItem.prototype.init = function(config){
    config.items = [];
    this.xType = 'treeItem';
    this.superCall('init', arguments, config);
    this.icons = config.icons;
    this.text = config.text;
    this.type = config.type || 0;//0 - Folder, 1 - Leaf, 2 - Undefined - Loading required
    this.collapsed = config.collapsed;
    this.children = [];
    this.hidden = config.hidden;
    this.loading = false;

    var instance = this;

    $(this.div).addClass('tree_item');
    this.elementDiv = core.newDiv(this.div, 'tree_item_element');

    $(this.elementDiv).click(function(){
        instance.tree.selectElement(instance);
        return false;
    });

    $(this.elementDiv).dblclick(function(){
        instance.tree.selectElement(instance);
        instance.collapseExpand();
        return false;
    });

    $(this.elementDiv).mousedown(function(e){
        instance.fire('mousedown', e);
        return false;
    });

    $(this.elementDiv).mousemove(function(e){
        instance.fire('mousemove', e);
        return false;
    });

    $(this.elementDiv).mouseup(function(e){
        instance.fire('mouseup', e);
        return false;
    });

    $(this.elementDiv).mouseout(function(e){
        instance.fire('mouseout', e);
        return false;
    });

    this.contentDiv = core.newDiv(this.elementDiv, 'tree_item_content');
    this.buttonDiv = core.newDiv(this.elementDiv, 'tree_item_button');
    $(this.buttonDiv).click(function(e){
        instance.collapseExpand();
        return false;
    });
};

core.tree.TreeItem.prototype.setParent = function(aParent){//TreeItem
    this.parent = aParent;
    if(aParent.tree!=this.tree){
        this.tree = aParent.tree;
        $(this.div).appendTo(this.tree.div);
        if(this.dd){
            this.enableDragging(this.tree, this, this.contentDiv);
        }
    }
};

core.tree.TreeItem.prototype.hide = function(){
    this.superCall('hide', arguments);
    for(var i = 0; i<this.children.length; i++){
        var ch = this.children[i];
        ch.hide();
    }
};

core.tree.TreeItem.prototype.resize = function(aX, aY, aWidth, aHeight){
//    core.log('resize0: ', aX, aY, aWidth, aHeight);
    var actualWidth = 0;
    var leftPadding = core.tree.TREE_LEVEL_PADDING;
    var topPadding = core.tree.TREE_ITEM_HEIGHT;

    if(this.hidden){
        $(this.contentDiv).hide();
        leftPadding = 0;
        topPadding = 0;
    }else{
        var icns = $.makeArray(this.icons);
        if(this.type!=1)
            icns.splice(0, 0);//Add left icon here
        $(this.contentDiv).html(core.Box.prototype.imagesToHTML(icns)+this.text);
        $(this.elementDiv).height(core.tree.TREE_ITEM_HEIGHT);
        var textPadding = 16;
        if(this.type==1){
            $(this.buttonDiv).hide();
        }else{
            $(this.buttonDiv).show();
            var im = 'im/tree/load.gif';
            if(!this.loading){
                im = this.collapsed?'im/tree/coll1.png':'im/tree/exp1.png';
            }
            $(this.buttonDiv).html('<img src="'+im+'" class="icon"/>');
            core.Box.prototype.alignBlock(this.buttonDiv, aWidth, core.tree.TREE_ITEM_HEIGHT, 'left', 'middle');
            textPadding = 16;
        }
        $(this.elementDiv).width(aWidth);
        core.Box.prototype.alignBlock(this.contentDiv, aWidth, core.tree.TREE_ITEM_HEIGHT, 'left', 'middle', textPadding);
        actualWidth = textPadding+$(this.contentDiv).width()+textPadding;
    }
    for(var i = 0; i<this.children.length; i++){
        var ch = this.children[i];
        if(this.collapsed)
            ch.hide();
        else{
            ch.show();
            ch.resize(aX+leftPadding, aY+topPadding, aWidth-leftPadding, core.tree.TREE_ITEM_HEIGHT);
            if(leftPadding+ch.width>actualWidth)
                actualWidth = leftPadding+ch.width;
            topPadding += ch.height;
        }
    }
//    core.log('resize: ', actualWidth, leftPadding, topPadding);
    this.height = topPadding;
    this.width = actualWidth;
    this.superCall('resize', arguments, aX, aY, aWidth, this.hidden?0:core.tree.TREE_ITEM_HEIGHT);
}

core.tree.TreeItem.prototype.loadComplete = function(aCollapse){
    this.loading = false;
    this.setCollapsed(aCollapse?true:false);
    this.refresh();
}

core.tree.TreeItem.prototype.setCollapsed = function(aCollapsed, aForceRefresh){
    if(this.type==1 || this.loading)//Leaf
        return false;
    var refresh = aCollapsed!=this.collapsed;
    this.collapsed = aCollapsed;
    if(refresh || aForceRefresh){
        if(!aCollapsed && this.type==2){
            this.loading = true;
            for(var i = 0; i<this.children.length; i++){
                this.children[i].remove(true);
            }
            this.children = [];
            this.fire('load', null, this);
        }
        this.tree.parent.refresh();
        return true;
    }
    return false;
};

core.tree.TreeItem.prototype.getChildCount = function(){
    if(this.type==1 || this.collapsed)
        return 0;
    return this.children.length;
}

core.tree.TreeItem.prototype.nextSibling = function(){
    if(!this.parent || !this.parent.children)
        return null;
    for(var i = 0; i<this.parent.children.length; i++){
        var ch = this.parent.children[i];
        if(ch==this && i<this.parent.children.length-1){
            return this.parent.children[i+1];
        }
    }
    return this.parent.nextSibling();
};

core.tree.TreeItem.prototype.prevSibling = function(){
    if(!this.parent || !this.parent.children)
        return null;
    for(var i in this.parent.children){
        var ch = this.parent.children[i];
        if(ch==this && i>0)
            return this.parent.children[i-1];
    }
    return null;
};

core.tree.TreeItem.prototype.removeFromParent = function(){
    if(this.parent && this.parent.children){
        for(var i = 0; i<this.parent.children.length; i++){
            if(this.parent.children[i]==this){
                this.parent.children.splice(i, 1);
                return;
            }
        }
    }
};

core.tree.TreeItem.prototype.remove = function(aKeepInChildren){
    for(var i = 0; i<this.children.length; i++){
        this.children[i].remove(true);
    }
    this.children = [];
    if(this.tree && this.tree.selectedElement==this)
        this.tree.selectedElement = null;
    this.tree = null;
    $(this.div).remove();
    if(!aKeepInChildren){
        this.removeFromParent();
    }

}

//core.tree.TreeItem.prototype.markAsDropTarget = function(aDropable){
//    this.superCall('markAsDropTarget', arguments, aDropable);
//    $(this.dropTargetDiv).height(core.tree.TREE_ITEM_HEIGHT);
//}
//
core.tree.TreeItem.prototype.acceptDraggable = function(aDraggable){
    aDraggable.removeFromParent();
    if(this.collapsed)
        this.setCollapsed(false);
    this.addChild(aDraggable);
}

core.tree.TreeItem.prototype.getDropTarget = function(aDraggable, aX, aY){
//    core.log('TreeItem:', this.text, this.bounds.y, aY);
    if(this.type==1)
        return null;
    if(aDraggable.tree==this.tree){
        var itm = this;
        do{
            if(itm==aDraggable)
                return null;
            itm = itm.parent;
        }while(itm);
    }
    if(!this.hidden && aY>=this.bounds.y && aY<=this.bounds.y+core.tree.TREE_ITEM_HEIGHT){
        return this;
    }else{
        if(!this.collapsed){
            for(var i = 0; i<this.children.length; i++){
                var res = this.children[i].getDropTarget(aDraggable, aX, aY);
                if(res)
                    return res;
            }
        }
    }
    return null;
};

core.tree.TreeItem.prototype.collapseExpand = function(){
    return this.setCollapsed(!this.collapsed);
};

core.tree.TreeItem.prototype.unselectMe = function(){
    $(this.elementDiv).removeClass('tree_item_element_selected');
}

core.tree.TreeItem.prototype.selectMe = function(){
    $(this.elementDiv).addClass('tree_item_element_selected');
}

core.tree.TreeItem.prototype.addChild = function(aChild){
    for(var i = 0; i<this.children.length; i++){
        if(this.children[i]==aChild){
            return null;
        }
    }
    aChild.setParent(this);
    this.children.push(aChild);
    this.tree.parent.refresh();
    return aChild;
};

core.tree.TreePanel = function(config){
    this.init(config);
};

core.extendClass('core.tree.TreePanel', 'core.form.UIControl');

core.tree.TreePanel.prototype.selectElement = function(aElement){
    this.fire('focus');
    if(aElement.tree!=this)
        return false;
    if(this.selectedElement==aElement)
        return false;
    if(this.selectedElement)
        this.selectedElement.unselectMe();
    this.selectedElement = aElement;
    this.selectedElement.selectMe();
    this.fire('select', {}, this.selectedElement);
    this.checkTreeItemVisible(aElement);
    return true;
}

core.tree.TreePanel.prototype.doKeyPress = function(e){
    if(e.which==38){//Top
        if(this.selectedElement){
            var s = this.selectedElement.prevSibling();
            if(!s)
                s = this.selectedElement.parent;
            if(s==this.root)
                s = null;
            if(s)
                this.selectElement(s);
        }
        return false;
    }
    if(e.which==40){//Bottom
        if(this.selectedElement){
            var s = null;
            if(this.selectedElement.getChildCount()>0)
                s = this.selectedElement.children[0];
            if(!s)
                s = this.selectedElement.nextSibling();
            if(s)
                this.selectElement(s);
        }
        return false;
    }
    if(e.which==37){//Left - collapse
        if(this.selectedElement)
            this.selectedElement.setCollapsed(true);
        return false;
    }
    if(e.which==39){//Right expand
        if(this.selectedElement)
            this.selectedElement.setCollapsed(false);
        return false;
    }
	return true;
}

core.tree.TreePanel.prototype.init = function(config){
    this.superCall('init', arguments, config);
    this.root = new core.tree.TreeItem({
        type: 0,
        hidden: true
    });
    this.root.setParent({
        tree: this,
        div: this.div,
        parent: this
    });
    this.root.parent = this;
    $(this.div).addClass('tree_panel');
};

core.tree.TreePanel.prototype.resize = function(aX, aY, aWidth, aHeight){
    this.root.resize(0, 0, aWidth, core.tree.TREE_ITEM_HEIGHT);
    this.superCall('resize', arguments, aX, aY, Math.max(this.root.width,aWidth), Math.max(this.root.height, aHeight));
};


core.tree.TreePanel.prototype.getDropTarget = function(aDraggable, aX, aY){
    var treeItem = this.root.getDropTarget(aDraggable, aX, aY);
    return treeItem;
};

core.tree.TreePanel.prototype.checkTreeItemVisible = function(aItem){
    if(!aItem)
        return;
    if($(this.div).parent().scrollTop()+this.height-core.tree.TREE_ITEM_HEIGHT-core.tree.SCROLLBAR_SIZE<aItem.bounds.y){
        $(this.div).parent().scrollTop(aItem.bounds.y+core.tree.TREE_ITEM_HEIGHT-this.height+core.tree.SCROLLBAR_SIZE);
        return;
    }
    if(aItem.bounds.y<$(this.div).parent().scrollTop()){
        $(this.div).parent().scrollTop(aItem.bounds.y);
        return;
    }
};

